
#include "LMI_I2C.h"
#include "rtos.h"

/*发送I2C初始化命令(初始化I2C总线设置与设备的通信)*/
void LMI::IIC_Initial() const {
    SCL_SetOutput();
    SCL_SetVal();
    SDA_SetOutput();
    SDA_SetVal();
}

LMI::LMI(uint8_t _scl, uint8_t _sda) {
    scl = _scl;
    sda = _sda;
    wire = new TwoWire(sda, scl);
    wire->begin();
}

int LMI::read(uint8_t id, float *temp, float *press) {
    BSP_IIC_Start(id);

    BSP_IIC_ByteWrite(0);
    BSP_IIC_ByteWrite(0x20);

    BSP_IIC_Stop();

    BSP_IIC_Start(id);

    BSP_IIC_ByteWrite(1);
    BSP_IIC_Stop();
    rtos::Delay(14);
    wire->requestFrom(id, (uint8_t) 4);
    BSP_IIC_ByteRead(2, 1);
    int press1 = ((I2C_Byte >> 8) | ((I2C_Byte & 0xFF) << 8));
    BSP_IIC_ByteRead(2, 0);
    int temp1 = ((I2C_Byte >> 8) | ((I2C_Byte & 0xFF) << 8));


    delayMicroseconds(100); //间隔在0.7ms以内数据准备时间为5mS，间隔大于0.7ms数据准备时间16ms

    BSP_IIC_Start(id);

    BSP_IIC_ByteWrite(1);
    BSP_IIC_Stop();
    rtos::Delay(4);
    wire->requestFrom(id, (uint8_t) 4);
    BSP_IIC_ByteRead(2, 1);
    int press2 = ((I2C_Byte >> 8) | ((I2C_Byte & 0xFF) << 8));
    BSP_IIC_ByteRead(2, 0);
    int temp2 = ((I2C_Byte >> 8) | ((I2C_Byte & 0xFF) << 8));


    if (temp2 >= 0x8000) //正负判断
        temp2 -= 0x10000;

    if (press2 >= 0x8000) //负数判断
        press2 -= 0x10000;

    *temp = (float) temp2 / 72 + 20;
    *press = (float) press2 / 1200; // LMIS025,Scale factor=1200
    return 0;
}

/*********************** SDA ********************************/
void LMI::BSP_IIC_Start(uint8_t id) const {
    if (wire) {
        wire->beginTransmission(id);
        return;
    }
    SDA_SetOutput();
    SCL_SetVal();
    SDA_SetVal();
    delayMicroseconds(2);
    SDA_ClrVal();
    delayMicroseconds(2);
    SCL_ClrVal();
    delayMicroseconds(2);
}

void LMI::BSP_IIC_Stop() const {
    if (wire) {
        wire->endTransmission();
        return;
    }
    SDA_SetOutput();
    SCL_ClrVal();
    SDA_ClrVal();
    delayMicroseconds(2);
    SCL_SetVal();
    delayMicroseconds(2);
    SDA_SetVal();
    delayMicroseconds(2);
}

void LMI::BSP_IIC_ByteWrite(uint8_t dat) const {
    if (wire) {
        wire->write(dat);
        return;
    }
    for (int i = 0; i < 8; i++) {
        if (dat & 0x80) {
            SDA_SetVal();
        } else {
            SDA_ClrVal();
        }
        dat <<= 1;
        delayMicroseconds(2);
        SCL_SetVal();
        delayMicroseconds(2);
        SCL_ClrVal();
        delayMicroseconds(2);
    }
    SDA_SetInput();
    SCL_SetVal();
    delayMicroseconds(2);
    SCL_ClrVal();
    delayMicroseconds(2);
    SDA_SetOutput();
}

void LMI::BSP_IIC_ByteRead(char lByte, char ack) {
    I2C_Byte = 0;

    for (int j = 0; j < lByte; j++) {
        if (wire) {
            I2C_Byte <<= 8;
            I2C_Byte |= wire->read();
        } else {
            SDA_SetInput();
            for (int i = 0; i < 8; i++) {
                SCL_SetVal();
                delayMicroseconds(2);
                I2C_Byte <<= 1;
                if (SDA_GetVal())
                    I2C_Byte |= 1;
                SCL_ClrVal();
                delayMicroseconds(2);
            }
            SDA_SetOutput();
            if ((ack == 0) && (j == lByte - 1)) {
                SDA_SetVal();
            } else {
                SDA_ClrVal();
            }
            delayMicroseconds(2);
            SCL_SetVal();
            delayMicroseconds(2);
            SCL_ClrVal();
            delayMicroseconds(2);
        }
    }
}
